package com.smedi.ismedi.organization.core.application.service.impl;

import com.smedi.ismedi.organization.core.application.command.ProjectOrganizationCommand;
import com.smedi.ismedi.organization.core.application.service.ProjectOrgManageApplicationService;
import com.smedi.ismedi.organization.core.domain.aggregatemodel.ProjectOrganization;
import com.smedi.ismedi.organization.core.domain.service.ProjectOrganizationDomainService;
import com.smedi.ismedi.organization.core.infrastructure.constant.CustomError;
import com.smedi.ismedi.web.starter.exception.LogicException;
import com.smedi.ismedi.web.starter.util.DozerUtil;
import lombok.AllArgsConstructor;
import lombok.extern.slf4j.Slf4j;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import java.util.List;

@Slf4j
@Service
@AllArgsConstructor
public class ProjectOrgManageApplicationServiceImpl implements ProjectOrgManageApplicationService {
    private final ProjectOrganizationDomainService projectOrganizationDomainService;

    private final DozerUtil dozerUtil;

    @Override
    @Transactional(rollbackFor = Exception.class)
    public ProjectOrganization saveProjectOrganization(ProjectOrganizationCommand projectOrganizationCommand) {
        ProjectOrganization projectOrganization = dozerUtil.convertor(projectOrganizationCommand, ProjectOrganization.class);
        ProjectOrganization basic = projectOrganizationDomainService.save(projectOrganization);

        if (basic.getParentId() != null) {
            ProjectOrganization parent = projectOrganizationDomainService.getProjectOrganizationByProjectOrganizationId(basic.getParentId());
            if (parent != null) {
                basic.setParentFullName(parent.getFullName())
                        .setParentShortName(parent.getShortName());
            } else {
                throw LogicException.raise(CustomError.PARENT_ORG_NOT_EXIST);
            }
        }

        return basic;
    }

    @Override
    public List<ProjectOrganization> getAllProjectOrganizationList() {
        return projectOrganizationDomainService.queryAll();
    }

    @Override
    @Transactional(rollbackFor = Exception.class)
    public void deleteProjectOrganization(Long projectOrganizationId) {
        projectOrganizationDomainService.delete(projectOrganizationId);
    }

    @Override
    public Boolean checkProjectOrganizationIsAvailable(Long projectOrganizationId) {
        return projectOrganizationDomainService.validateProjectOrganization(projectOrganizationId);
    }

    @Override
    public Boolean checkProjectOrganizationCanBeConfigOrganization(Long projectOrganizationId) {
        return projectOrganizationDomainService.validateProjectOrganizationCanBeConfigOrg(projectOrganizationId);
    }

    @Override
    public Boolean checkProjectOrganizationIsExternalUnit(Long projectOrganizationId) {
        return projectOrganizationDomainService.validateProjectOrganizationIsExternalUnit(projectOrganizationId);
    }

    @Override
    public void exchangeTwoProjectOrganizationNodeSort(ProjectOrganizationCommand projectOrganizationCommandPartOne, ProjectOrganizationCommand projectOrganizationCommandPartTwo) {
        if (projectOrganizationCommandPartOne == null || projectOrganizationCommandPartTwo == null) {
            throw LogicException.raise(CustomError.EXCHANGE_NODE_MISS_ONE_NODE);
        }

        projectOrganizationDomainService.saveProjectOrganizationDisplayOrder(projectOrganizationCommandPartOne.getProjectOrganizationId(), projectOrganizationCommandPartOne.getDisplayOrder());
        projectOrganizationDomainService.saveProjectOrganizationDisplayOrder(projectOrganizationCommandPartTwo.getProjectOrganizationId(), projectOrganizationCommandPartTwo.getDisplayOrder());
    }
}
